package org.albino.evinreisi.facebook;

import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.restfb.Connection;
import com.restfb.DefaultFacebookClient;
import com.restfb.DefaultLegacyFacebookClient;
import com.restfb.FacebookClient;
import com.restfb.LegacyFacebookClient;
import com.restfb.Parameter;
import com.restfb.types.FacebookType;
import com.restfb.types.User;

public class FacebookServiceImpl implements FacebookService {
	private static final Logger log = Logger.getLogger(FacebookServiceImpl.class.getName());

	FacebookClient client = null;
	LegacyFacebookClient oldClient = null;

	public FacebookServiceImpl(String token) {
		client = new DefaultFacebookClient(token);
		oldClient = new DefaultLegacyFacebookClient(token);
	}

	@Override
	public Map<String, FacebookUser> getFriends() {
		try {
			Map<String, FacebookUser> friends = new HashMap<String, FacebookUser>();
			Connection<User> friendsConnection = client.fetchConnection("me/friends", User.class);

			for (User friend : friendsConnection.getData()) {
				friends.put(friend.getId(), new FacebookUser(friend));
			}

			return friends;
		} catch (Exception e) {
			log.log(Level.SEVERE, "Exception occured while getting friends", e);

			throw new IllegalStateException("Exception occured while getting friends");
		}

	}

	@Override
	public FacebookUser getSelf() {
		try {
			User user = client.fetchObject("me", User.class);

			return new FacebookUser(user);
		} catch (Exception e) {
			log.log(Level.SEVERE, "Exception occured while getting self", e);

			throw new IllegalStateException("Exception occured while getting self");
		}
	}

	@Override
	public boolean publishStory(String title, String description) {
		return publishStory(title, description, null, null);
	}

	@Override
	public boolean publishStory(String title, String description, String link, String caption) {
		log.finest("publishStory is called.");
		log.finest("title = " + title);
		log.finest("description = " + description);
		log.finest("link = " + link);
		log.finest("caption = " + caption);

		try {
			FacebookType publishMessageResponse = null;

			if (link != null && caption != null)
				publishMessageResponse = client.publish("me/feed", FacebookType.class, Parameter.with("message", title), Parameter.with("description",
						description), Parameter.with("link", link), Parameter.with("caption", caption), Parameter.with("picture",
						"http://upload.wikimedia.org/wikipedia/hu/f/f9/Fenerbahce_hqfl_logo.png"));
			else
				publishMessageResponse = client.publish("me/feed", FacebookType.class, Parameter.with("message", title), Parameter.with("description",
						description), Parameter.with("picture", "http://upload.wikimedia.org/wikipedia/hu/f/f9/Fenerbahce_hqfl_logo.png"));

			log.info("publish message response = " + publishMessageResponse);
			return true;
		} catch (Exception e) {
			log.log(Level.SEVERE, "Exception occured while publishing story", e);

			throw new IllegalStateException("Exception occured while publishing story");
		}
	}

	@Override
	public boolean createEvent(String title, String description, Date startDate, Date endDate) {
		try {

			Long tomorrow = System.currentTimeMillis() / 1000L + 60L * 60L * 24L;
			Long twoDaysFromNow = System.currentTimeMillis() / 1000L + 60L * 60L * 48L;

			GregorianCalendar start = new GregorianCalendar();
			start.setTime(startDate);
			GregorianCalendar end = new GregorianCalendar();
			end.setTime(endDate);

			FacebookType publishEventResponse = client.publish("me/events", FacebookType.class, Parameter.with("name", title), Parameter.with("description",
					description), Parameter.with("start_time", tomorrow), Parameter.with("end_time", twoDaysFromNow));

//			FacebookType publishEventResponse = client.publish("me/events", FacebookType.class, Parameter.with("name", title), Parameter.with("description",
//					description), Parameter.with("start_time", start.getTimeInMillis()), Parameter.with("end_time", end.getTimeInMillis()));

			
			log.info("publish event response = " + publishEventResponse);
			return true;
		} catch (Exception e) {
			log.log(Level.SEVERE, "Exception occured while publishing event", e);

			throw new IllegalStateException("Exception occured while publishing story");
		}
	}

	@Override
	public boolean inviteFriendsToEvent(String eventId, List<String> friendIds, String personalMessage) {
		try {
			oldClient.execute("events.invite", Parameter.with("eid", eventId), Parameter.with("uids", Util.friendIdsToCSV(friendIds)), Parameter.with("personal_message",
					personalMessage));
			return true;

		} catch (Exception e) {
			log.log(Level.SEVERE, "Exception occured while inviting friends", e);
			return false;
		}
	}

}